﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;

namespace YF_Music.Core.Mvvm
{
  public class AsyncDelegateCommand : ICommand
  {
    private readonly Func<Task> _execute;
    private readonly Func<bool> _canExecute;
    private bool _isExecuting;

    public event EventHandler? CanExecuteChanged;

    public AsyncDelegateCommand(Func<Task> execute, Func<bool> canExecute = null)
    {
      _execute = execute ?? throw new ArgumentNullException(nameof(execute));
      _canExecute = canExecute;
    }

    public bool CanExecute(object? parameter)
    {
      return !_isExecuting && (_canExecute?.Invoke() ?? true);
    }

    public async void Execute(object? parameter)
    {
      if (!CanExecute(parameter))
        return;

      try
      {
        _isExecuting = true;
        RaiseCanExecuteChanged();
        await _execute();
      }
      finally
      {
        _isExecuting = false;
        RaiseCanExecuteChanged();
      }
    }

    public void RaiseCanExecuteChanged()
    {
      CanExecuteChanged?.Invoke(this, EventArgs.Empty);
    }
  }
}
